﻿//
// Lightbox Gallery Module for DotNetNuke
// Project Contributors - Will Strohl (http://www.WillStrohl.com), Armand Datema (http://www.schwingsoft.com)
//
//Copyright (c) 2009-2013, Will Strohl
//All rights reserved.
//
//Redistribution and use in source and binary forms, with or without modification, are 
//permitted provided that the following conditions are met:
//
//Redistributions of source code must retain the above copyright notice, this list of 
//conditions and the following disclaimer.
//
//Redistributions in binary form must reproduce the above copyright notice, this list 
//of conditions and the following disclaimer in the documentation and/or other 
//materials provided with the distribution.
//
//Neither the name of Will Strohl, Armand Datema, Lightbox Gallery, nor the names of its contributors may be 
//used to endorse or promote products derived from this software without specific prior 
//written permission.
//
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
//EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
//OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
//SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 
//TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 
//BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
//CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 
//DAMAGE.
//

//INSTANT C# NOTE: Formerly VB project-level imports:

using System.Globalization;
using DotNetNuke.Common.Utilities;
using System;
using Danielyan.Exif;
using DotNetNuke.Security;
using DotNetNuke.Services.Exceptions;
using DotNetNuke.Services.FileSystem;
using System.Drawing;
using System.Text;
using System.Web.UI;
using System.Collections.Generic;
using DotNetNuke.UI.Skins;
using DotNetNuke.UI.Skins.Controls;

namespace WillStrohl.Modules.Lightbox
{

    public partial class EditImage : WnsPortalModuleBase
    {

        #region  Private Members

        private const string IMAGE_FORMAT = "<a href=\"{0}\" target=\"_blank\"><img class=\"wns-image\" src=\"{0}\" alt=\"{1}\" title=\"{1}\"{2} /></a>";

        private int p_ImageId = Null.NullInteger;
        private int p_LightboxId = Null.NullInteger;

        #endregion

        #region  Properties

        private int ImageId
        {
            get
            {
                if (p_ImageId > 0)
                {
                    return p_ImageId;
                }

                var image = Request.QueryString["Image"];
                int.TryParse(image.ToString(CultureInfo.InvariantCulture), out p_ImageId);

                return p_ImageId;
            }
        }

        private int LightboxId
        {
            get
            {
                if (p_LightboxId > 0)
                {
                    return p_LightboxId;
                }

                int.TryParse(Request.QueryString["Album"], out p_LightboxId);

                return p_LightboxId;
            }
        }

        #endregion

        #region  Event Handlers

        /// <summary>
        /// OnInit - initialization of the module
        /// </summary>
        /// <param name="e"></param>
        override protected void OnInit(EventArgs e)
        {
            InitializeComponent();
            base.OnInit(e);
        }

        private void InitializeComponent()
        {
            Load += new System.EventHandler(Page_Load);
            cmdCancel.Click += new System.EventHandler(cmdCancel_Click);
            cmdUpdate.Click += new System.EventHandler(cmdUpdate_Click);
            cmdDelete.Click += new System.EventHandler(cmdDelete_Click);
        }

        private void Page_Load(object sender, EventArgs e)
        {
            try
            {
                if (AllowedToEditModule() == false)
                {
                    Response.Redirect(GetDefaultViewUrl());
                }

                if (ImageId < 1)
                {
                    SendToModule();
                }

                if (!Page.IsPostBack)
                {
                    BindData();
                }

                Page.Header.Controls.Add(new LiteralControl(string.Format(LightboxController.STYLESHEET_TAG_FORMAT, string.Concat(ControlPath, "js/jquery-ui-1.8.2.css"))));

            }
            catch (Exception exc) // Module failed to load
            {
                Exceptions.ProcessModuleLoadException(this, exc, IsEditable);
            }
        }

        private void cmdCancel_Click(object sender, System.EventArgs e)
        {
            SendToModule();
        }

        private void cmdUpdate_Click(object sender, System.EventArgs e)
        {

            if (Page.IsValid)
            {
                SaveImage();
            }

        }

        private void cmdDelete_Click(object sender, System.EventArgs e)
        {
            DeleteImage();
        }

        #endregion

        #region  Private Helper Functions

        private void BindData()
        {

            LocalizeModule();

            var ctlModule = new LightboxController();

            var oImage = ctlModule.GetImageById(ImageId);
            var oLightbox = ctlModule.GetLightbox(LightboxId);

            if (oImage != null)
            {
                txtImageDescription.Text = oImage.Description;
                txtImageTitle.Text = oImage.Title;
            }

            var strDimensions = string.Empty;
            var imgFile = ctlModule.GetImageFromProvider(PortalId, oLightbox.GalleryFolder, oImage.FileName);

            if (imgFile != null)
            {

                if (imgFile.Width > 500)
                {
                    strDimensions = GetDimensions(imgFile);
                }

                WriteImageMetaData(imgFile);

            }
            else
            {

                SendToModule();

            }

            litImage.Text = string.Format(IMAGE_FORMAT, ctlModule.GetImageFileUrl(imgFile), oImage.Title, strDimensions);

            lblFileName.Text = string.Format("{0} &gt; {1}", oLightbox.GalleryName, oImage.FileName);

            cmdDelete.Visible = (ImageId != Null.NullInteger);

        }

        private void WriteImageMetaData(IFileInfo img)
		{

			// need to determine if the image is in a local folder
			var ctlModule = new LightboxController();
			Image oImage = null;

			if (ctlModule.IsLocalFolder(img))
			{
				// need to grab an image from local or cloud
				// local can use Image.FromFile
				oImage = Image.FromFile(img.PhysicalPath);
			}
			else
			{
				// cloud requires pulling the image from HTTP stream
				System.Net.WebRequest extRequest = System.Net.WebRequest.Create(ctlModule.GetImageFileUrl(img));
				//get the external response 
				System.Net.WebResponse extResponse = extRequest.GetResponse();
				//get the external responses stream 
				oImage = Image.FromStream(extResponse.GetResponseStream());
				//clear our buffer and set up our response 
				Context.Response.Clear();
				Context.Response.Buffer = false;
			}

			var sb = new StringBuilder();
			var tags = new ExifTags(oImage);

			foreach(KeyValuePair<string, ExifTag> oProp in tags)
			{

				switch (oProp.Key)
				{
					case "PixelXDimension":
					case "PixelYDimension":
						sb.AppendFormat("<div class=\"dnnClear\"><label class=\"wnsExifTitle wnsExifInline\">{0}:</label>&nbsp; <span class=\"Normal wnsExifInline\">{1} px</span></div>", oProp.Value.Description, oProp.Value.Value);
						break;
					case "DateTime":
					case "DateTimeOriginal":
					case "DateTimeDigitized":
				        DateTime dteValue;
                        DateTime.TryParse(oProp.Value.Value, out dteValue);

                        if (dteValue != DateTime.MinValue)
                        {
                            sb.AppendFormat(
                                "<div class=\"dnnClear\"><label class=\"wnsExifTitle wnsExifTitle\">{0}:</label>&nbsp; <span class=\"Normal wnsExifInline\">{1}</span></div>",
                                oProp.Value.Description, dteValue);
                        }
                        else
                        {
                            sb.AppendFormat(
                                "<div class=\"dnnClear\"><label class=\"wnsExifTitle wnsExifTitle\">{0}:</label>&nbsp; <span class=\"Normal wnsExifInline\">{1}</span></div>",
                                oProp.Value.Description, oProp.Value.Value);
                        }
				        break;
					case "Flash":
					case "ExposureMode":
					case "WhiteBalance":
					case "ShutterSpeedValue":
					case "ApertureValue":
					case "Make":
					case "Model":
					case "Software":
						sb.AppendFormat("<div class=\"dnnClear\"><label class=\"wnsExifTitle wnsExifTitle\">{0}:</label>&nbsp; <span class=\"Normal wnsExifInline\">{1}</span></div>", oProp.Value.Description, oProp.Value.Value);
						break;
				}

				//*** for debug only - shows all possible properties ***
				//sb.AppendFormat("<div class=""dnnClear""><span class=""SubHead wnsExifTitle"">{0}:</span>&nbsp; <span class=""Normal"">{1}; {2}</span></div>", _
				//    oProp.Key, _
				//    oProp.Value.Description, _
				//    oProp.Value.Value)
				//*** end of debug ***
			}

			divImageMetaData.InnerHtml = sb.ToString();

		}

        private string GetDimensions(IFileInfo oImage)
        {

            int NewWidth = 500;
            int MaxHeight = 500;

            if (oImage.Width <= NewWidth)
            {
                NewWidth = oImage.Width;
            }

            int NewHeight = Convert.ToInt32(oImage.Height * NewWidth / (double)oImage.Width);

            if (NewHeight > MaxHeight)
            {
                NewWidth = Convert.ToInt32(oImage.Width * MaxHeight / (double)oImage.Height);
                NewHeight = MaxHeight;
            }

            return string.Format(" height=\"{0}\" width=\"{1}\"", NewHeight.ToString(), NewWidth.ToString());

        }

        private void LocalizeModule()
        {

            cmdCancel.Text = GetLocalizedString("cmdCancel.Text");
            cmdUpdate.Text = GetLocalizedString("cmdUpdate.Text");
            cmdDelete.Text = GetLocalizedString("cmdDelete.Text");

            rfvImageDescription.ErrorMessage = GetLocalizedString("rfvImageDescription.ErrorMessage");
            rfvImageTitle.ErrorMessage = GetLocalizedString("rfvImageTitle.ErrorMessage");

        }

        private void SaveImage()
        {

            var ctlModule = new LightboxController();
            var oImage = ctlModule.GetImageById(ImageId);
            var sec = new PortalSecurity();

            oImage.Title = sec.InputFilter(txtImageTitle.Text.Trim(), PortalSecurity.FilterFlag.NoMarkup);
            oImage.Description = sec.InputFilter(txtImageDescription.Text.Trim(), PortalSecurity.FilterFlag.NoScripting);

            ctlModule.UpdateImage(oImage.ImageId, oImage.LightboxId, oImage.FileName, oImage.Title, oImage.Description, oImage.DisplayOrder, UserId);

            SendToModule();

        }

        private void DeleteImage()
        {

            if (ImageId != Null.NullInteger)
            {

                var ctlLightbox = new LightboxController();
                var oLightbox = ctlLightbox.GetLightbox(LightboxId);
                var oImage = ctlLightbox.GetImageById(ImageId);
                var oFolder = FolderManager.Instance.GetFolder(PortalId, oLightbox.GalleryFolder);

                if (FileManager.Instance.FileExists(oFolder, oImage.FileName))
                {

                    var oFile = FileManager.Instance.GetFile(oFolder, oImage.FileName);
                    FileManager.Instance.DeleteFile(oFile);

                    var strThumbnail = LightboxController.GetThumbnailImageName(oImage.FileName, PortalSettings, false);

                    if (FileManager.Instance.FileExists(oFolder, strThumbnail))
                    {
                        oFile = FileManager.Instance.GetFile(oFolder, strThumbnail);
                        FileManager.Instance.DeleteFile(oFile);
                    }

                    ctlLightbox.DeleteImageById(ImageId);

                }

                SendToModule();

            }

        }

        private void SendToModule()
        {

            Response.Redirect(GetDefaultViewUrl());

        }

        private void HandleException(Exception exc)
        {
            Exceptions.LogException(exc);
            if (UserInfo.IsSuperUser || UserInfo.UserID == PortalSettings.AdministratorId)
            {
                Skin.AddModuleMessage(this, string.Concat(exc.Message, "<br />", exc.StackTrace), ModuleMessage.ModuleMessageType.RedError);
            }
            else
            {
                Skin.AddModuleMessage(this, exc.Message, ModuleMessage.ModuleMessageType.RedError);
            }
        }

        #endregion

    }

}